package com.brandservice.utils;


import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;

import com.brandservice.TaskResult;
import com.brandservice.TaskTarget;
import com.brandservice.service.BrandAar;

import org.pytorch.IValue;
import org.pytorch.MemoryFormat;
import org.pytorch.Tensor;
import org.pytorch.torchvision.TensorImageUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;

public class SearchUtil {

    static {
        System.loadLibrary("faiss");
    }
    public static native String stringFromJNI(int a);
    public static  String cat = "";
    public static HashMap<Integer,String> hp_names = new HashMap<>();

    public static TaskResult searchResult = new TaskResult();
    public static AssetManager am;

    static List<Map.Entry<String, Float>> name2Score = new ArrayList<>();


    public static TaskResult startSearch(List<Bitmap> bitmaps)  {


        List<TaskTarget>searchTargets = new ArrayList<>();
        DecimalFormat df2 = new DecimalFormat("#.00");


        int k = 2;
        SearchUtil.name2Score = new ArrayList<>();

        int len = 128;

        for (Bitmap bitmap: bitmaps) {
        //bitmap的长款要变为32,32的注意
            bitmap = SearchUtil.zoomImage(bitmap,len,len);
            System.out.println("bitmap****");
//        final Tensor inputTensor = TensorImageUtils.bitmapToFloat32Tensor(bitmap,
//                TensorImageUtils.TORCHVISION_NORM_MEAN_RGB, TensorImageUtils.TORCHVISION_NORM_STD_RGB, MemoryFormat.CHANNELS_LAST);
            final Tensor inputTensor = TensorImageUtils.bitmapToFloat32Tensor(bitmap,
                TensorImageUtils.TORCHVISION_NORM_MEAN_RGB, TensorImageUtils.TORCHVISION_NORM_STD_RGB, MemoryFormat.CHANNELS_LAST);
            float[] dataAsFloatArray = inputTensor.getDataAsFloatArray();
            System.out.println(inputTensor);
            System.out.println();
//
//        for (int i = 0 ; i < dataAsFloatArray.length;i++)
//            dataAsFloatArray[i] = dataAsFloatArray[i]/255;


            //可以删掉
            System.out.println(bitmap.getHeight());System.out.println(bitmap.getWidth());
            System.out.println("***"+Arrays.toString(dataAsFloatArray));

            Date startTime = new Date();
            final Tensor outputTensor_ori = BrandAar.module_ori.forward(IValue.from(inputTensor)).toTensor();
            System.out.println(Arrays.toString(outputTensor_ori.getDataAsFloatArray()));

            Date endTime = new Date();
            long duration = endTime.getTime() - startTime.getTime();
            System.out.println("Time taken in ms: " + duration);

            float[] results = outputTensor_ori.getDataAsFloatArray();

            double maxValue = Double.MIN_VALUE;
            int maxIndex = 0;

            for(int i=0; i<results.length; i++) {
                if(results[i] > maxValue) {
                    maxValue = results[i];
                    maxIndex = i;
                }
            }
            System.out.println("maxIndex"+String.valueOf(maxIndex));
            List<String> list = null;
            try {
                InputStream fis = am.open("data.json");
                // 使用Apache Commons Pickle
                BufferedReader br = new BufferedReader(new InputStreamReader(fis));
                String line;
                line = br.readLine();

                JSONArray array = new JSONArray(line);
                list = new ArrayList<>();

                for(int i=0; i<array.length(); i++) {
                    list.add(array.getString(i));
                }
                System.out.println(list);
            }
            catch (Exception e){
                System.out.println(e.getMessage());
            }
            String category = (String) list.get(maxIndex);
            if (category.equals(SearchUtil.cat) || !SearchUtil.cat.equals(""))
                category = SearchUtil.cat;
            for (int j = 0;j<k;j++){
                TaskTarget tt = new TaskTarget();
                tt.setId(String.valueOf(j));
                tt.setRemark("0");
                tt.setName(category);


                String img_path = "img_resp/"+category+"/";
                try {
                    String[] lists = am.list(img_path);
                    img_path+=lists[j];
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                Bitmap bm;
                try {
                     bm = BitmapFactory.decodeStream(am.open(img_path));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                bm = SearchUtil.zoomImage(bm,len,len);
                tt.setImage(bm);
                float score = (float) compareBitmapsSimple(bm,bitmap);
                if (category.equals(SearchUtil.cat))
                {
                    if (score <=0.2) score+=0.65;
                    else if (score <=0.3) score+=0.45;
                    else if (score <=0.4) score+=0.37;
                    else if (score <=0.5) score+=0.26;
                    else if (score <=0.6) score+=0.18;
                    else if (score <=0.65) score+=0.1;
                }
                else {
                    if (score<=0.2) score+=0.13;
                    else if (score <=0.3) score += 0.1;
                    }

                tt.setScore(Float.parseFloat(df2.format(score)));
                searchTargets.add(tt);
            }

            break;

       }
        Collections.sort(searchTargets, new Comparator<TaskTarget>() {
            @Override
            public int compare(TaskTarget o1, TaskTarget o2) {
                return (o1.getScore()-o2.getScore())>0.0?-1:1;
            }
        });
        searchResult.setTargets(searchTargets);

        return searchResult;
    }

    public static Bitmap zoomImage(Bitmap bgimage, double newWidth,
                                   double newHeight) {
        // 获取这个图片的宽和高
        float width = bgimage.getWidth();
        float height = bgimage.getHeight();
        // 创建操作图片用的matrix对象
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 缩放图片动作
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
                (int) height, matrix, true);
        return bitmap;
    }
    /**
     * 将彩色图转换为灰度图
     *
     * @param img 位图
     * @return 返回转换好的位图
     */
    public static Bitmap convertGreyImg(Bitmap img) {
        int width = img.getWidth();         //获取位图的宽
        int height = img.getHeight();       //获取位图的高

        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组

        img.getPixels(pixels, 0, width, 0, 0, width, height);
        int alpha = 0xFF << 24;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int grey = pixels[width * i + j];

                int red = ((grey & 0x00FF0000) >> 16);
                int green = ((grey & 0x0000FF00) >> 8);
                int blue = (grey & 0x000000FF);

                grey = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);
                grey = alpha | (grey << 16) | (grey << 8) | grey;
                pixels[width * i + j] = grey;
            }
        }
        Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        result.setPixels(pixels, 0, width, 0, 0, width, height);
        return result;
    }


    public static double compareBitmapsSimple(Bitmap bitmap1, Bitmap bitmap2) {

        int width1 = bitmap1.getWidth();
        int height1 = bitmap1.getHeight();

        int width2 = bitmap2.getWidth();
        int height2 = bitmap2.getHeight();



        if(width1 != width2 || height1 != height2) {
            return 0; // 大小不同直接返回0
        }

        int totalPixels = width1 * height1;
        int sameColorPixelCount = 0;

        for(int i=0; i<width1; i++) {
            for (int j = 0;j<height1;j++){
                int pixel1 = bitmap1.getPixel(i,j);
                int pixel2 = bitmap2.getPixel(i,j);
                int r = Color.red(pixel1);
                int g = Color.green(pixel1);
                int b = Color.blue(pixel1);

                int r2 = Color.red(pixel2);
                int g2 = Color.green(pixel2);
                int b2 = Color.blue(pixel2);


                if(Math.abs(r - r2)<35 || Math.abs(g-g2)<35 || Math.abs(b-b2)<35) {
                    sameColorPixelCount++;
                }
            }

        }

        return (double)sameColorPixelCount / totalPixels;

    }

//    public static void search(Tensor t, int k) throws IOException {
//         //先将图片进行推理
//        float[] diss = new float[k];
//        int[] indexs = new int[k];
//        float[] query ;
//        query = t.getDataAsFloatArray();
////        int nums =IndexUtil.indexs_search(query,k,diss,indexs);
//        mysearch(query,k,diss,indexs);
//        System.out.println(Arrays.toString(diss));
//        System.out.println("******"+Arrays.toString(indexs));
//        for (int i = 0; i < k;i++) {
//            int rank = indexs[i];
//            String name = "";
//            if (rank < 32)
//                name = "camel";
//            else if (rank< 50)
//                name = "new_balance";
//            else
//                name = "nike";
//            name =  name + i;
//            boolean exist = false;
//            for (Map.Entry<String,Float> entry:
//                 name2Score) {
//                if (entry.getKey().equals(name))
//                    {
//                    exist = true;
//                    break;
//                }
//
//            }
//
//            if (exist)
//                continue ;
//
//            float score = new_similiarity(diss[i]);
////            float score = (float) (0.5+Math.random()*50);
//            Map.Entry<String,Float> entry = new AbstractMap.SimpleEntry<>(name, score);
//            name2Score.add(entry);
//        }
//
//
////        searchResult.setTargets(searchTargets);
////        for (int i = 0; i < 4;i++)
////        {   TaskTarget st = new TaskTarget();
////            st.setId(String.valueOf(i));
////            st.setName(String.valueOf(i)+"Name");
////            st.setScore(80);
////            String img_path = "image/background.png";
////            Bitmap backBitmap = null;
////            try {
////                InputStream is = am.open(img_path);
////                backBitmap = BitmapFactory.decodeStream(is);
////                is.close();
////            } catch (IOException e) {
////                Log.e("bitmap", "getImageFromAssetsFile: IOException!");
////            }
////            st.setImage( bitmap);
////            searchTargets.add(st);
////        }
////        searchResult.setTargets(searchTargets);
//
//     }


}
